package hos.thread;

import android.util.Log;

import hos.thread.executor.TS;
import hos.thread.hander.MH;

/**
 * <p>Title: RunnableLife </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2023/8/10 8:53
 */
public abstract class RunnableLife implements RunnableThis {


    private boolean isCancel = false;

    public boolean isCancel() {
        return isCancel;
    }

    public RunnableLife reset() {
        isCancel = false;
        return this;
    }

    public void cancel() {
        changedStatus(ThreadOption.Status.ON_CANCEL);
        isCancel = true;
    }

    protected ThreadOption.onThrowableListener onThrowable = null;

    protected ThreadOption.onCancelListener onCancel = null;

    protected ThreadOption.onProgressListener onProgress = null;

    protected ThreadOption.onStartListener onStart = null;

    private ThreadOption.onStatusChangedListener listener = null;

    private ThreadOption.Status status = ThreadOption.Status.ON_NONE;

    protected void changedStatus(ThreadOption.Status status) {
        this.status = status;
        if (listener != null) {
            listener.onStart(this, status);
        }
    }

    public boolean isStatus(ThreadOption.Status status) {
        return this.status == status;
    }

    public boolean isRunning() {
        return (isStatus(ThreadOption.Status.ON_START) || isStatus(ThreadOption.Status.ON_RUNNING));
    }

    public RunnableLife setStatusListener(ThreadOption.onStatusChangedListener listener) {
        this.listener = listener;
        return this;
    }

    public RunnableLife onStart(ThreadOption.onStartListener start) {
        this.onStart = start;
        return this;
    }

    public RunnableLife onProgress(ThreadOption.onProgressListener progress) {
        this.onProgress = progress;
        return this;
    }

    public RunnableLife onCatch(ThreadOption.onThrowableListener throwable) {
        this.onThrowable = throwable;
        return this;
    }

    public RunnableLife onCancel(ThreadOption.onCancelListener onCancel) {
        this.onCancel = onCancel;
        return this;
    }

    protected void postStart() {
        Log.d("Thread", "onStart");
        runUI(() -> {
            if (onStart != null) {
                onStart.onStart(this);
            }
        });
        changedStatus(ThreadOption.Status.ON_START);
    }

    protected void postCancel() {
        Log.d("Thread", "onCancel");
        runUI(() -> {
            if (onCancel != null) {
                onCancel.onCancel();
            }
        });
    }

    protected void postProgress(Double value) {
        Log.d("Thread", "onProgress: " + value);
        runUI(() -> {
            if (onProgress != null) {
                onProgress.onProgress(value);
            }
        });
    }

    protected void postThrowable(
            Throwable throwable
    ) {
        postThrowable(throwable, Thread.currentThread().getName());
    }

    protected void postThrowable(
            Throwable throwable,
            String threadName
    ) {
        Log.e("Thread", "onError", throwable);
        runUI(() -> {
            if (onThrowable != null) {
                onThrowable.onThrowable(throwable, threadName);
            }
        });
        changedStatus(ThreadOption.Status.ON_THROWABLE);
    }

    protected void runUI(Runnable runnable) {
        MH.run(runnable);
    }

    public abstract void progressUpdate(Double value);

    public void onDestroy() {
        cancel();
        changedStatus(ThreadOption.Status.ON_DESTROY);
        TS.remove(this);
        onProgress = null;
        onCancel = null;
        onStart = null;
        onThrowable = null;
        listener = null;
    }
}
